﻿using FFmpegDecodecVideo.AttributeUsageFolder;
using FFmpegDecodecVideo.FFmpegUlit;
using Microsoft.Graphics.Canvas;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Foundation.Collections;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.

namespace FFmpegDecodecVideo.Views
{
    [PageInfoAttibute("解码音频")]
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public unsafe sealed partial class FFmpegDecodecAudio : Page
    {
        Task PlayTask;
        CanvasBitmap bitmap;
        DispatcherTimer timer = new DispatcherTimer();
        bool progressActivity = false;
        DecodecAudio audio = new DecodecAudio();

        //缓存时间（ms）
        const int BUFFER_DURATION = 2000;
        //NAudio音频播放组件
        private WaveOut waveOut;
        private BufferedWaveProvider bufferedWaveProvider;
        public FFmpegDecodecAudio()
        {
            this.InitializeComponent();
            Init();
            InitUi();
        }
        void Init()
        {
            waveOut = new WaveOut();
            bufferedWaveProvider = new BufferedWaveProvider(new WaveFormat());
            waveOut.Init(bufferedWaveProvider);
            waveOut.Play();
            //播放
            play.Click += (s, e) =>
            {
                if (audio.State == MediaState.None)
                {
                    //初始化解码视频
                    audio.InitDecodecAudio(pathBox.Text);
                    DisplayVideoInfo();
                }
                audio.Play();
                timer.Start();
            };
            //暂停
            pause.Click += (s, e) => audio.Pause();
            stop.Click += (s, e) => audio.Stop(); ;
            PlayTask = new Task(() =>
            {
                while (true)
                {
                    //播放中
                    if (audio.IsPlaying)
                    {
                        //获取下一帧视频
                        if (audio.TryReadNextFrame(out var frame))
                        {
                            var bytes = audio.FrameConvertBytes(&frame);
                            if (bytes == null)
                                continue;
                            if (bufferedWaveProvider.BufferLength <= bufferedWaveProvider.BufferedBytes+bytes.Length)
                            {
                                bufferedWaveProvider.ClearBuffer();
                            }
                            bufferedWaveProvider.AddSamples(bytes, 0, bytes.Length);//向缓存中添加音频样本
                        }
                    }
                }
            });
            PlayTask.Start();
            audio.MediaCompleted += (s) =>
            {
                DispatcherQueue.TryEnqueue(Microsoft.UI.Dispatching.DispatcherQueuePriority.Normal, () =>
                {
                    timer.Stop();
                    progressActivity = false;
                    DisplayVideoInfo();
                });
            };
        }
        void InitUi()
        {
            //画布绘制
            canvas.Draw += (s, e) =>
            {
                if (bitmap != null)
                {
                    var te = Win2DUlit.CalcutateImageCenteredTransform(canvas.ActualSize, bitmap.Size);
                    te.Source = bitmap;
                    e.DrawingSession.DrawImage(te);
                }
            };
            timer.Interval = TimeSpan.FromMilliseconds(300);
            //计时器更新进度条
            timer.Tick += (s, e) =>
            {
                if (!audio.IsPlaying)
                    return;
                position.Text = audio.Position.ToString();
                progressActivity = false;
                progress.Value = audio.Position.TotalSeconds;
                progressActivity = true;
            };
            //进度条更改
            progress.ValueChanged += (s, e) =>
            {
                if (!audio.IsPlaying)
                    return;
                if (progressActivity == true)
                {
                    audio.SeekProgress((int)e.NewValue);
                }
            };
        }

        /// <summary>
        /// 显示视频信息
        /// </summary>
        void DisplayVideoInfo()
        {
            dura.Text = audio.Duration.ToString();
            audioCodec.Text = audio.CodecName;
            audioBitrate.Text = audio.Bitrate.ToString();
            audioChannels.Text = audio.Channels.ToString();
            audioChannelsLayout .Text = audio.ChannelLyaout.ToString();
            audioSampleRate.Text = audio.SampleRate.ToString();
            audioBitsPerSample.Text = audio.BitsPerSample.ToString();
            position.Text = audio.Position.ToString();
            progress.Maximum = audio.Duration.TotalSeconds;
        }
    }
}
